<template>
  <div class="p2">
    <!-- 左侧关系图窗口 -->
    <el-card
      class="graph-card"
      shadow="hover"
      :body-style="{ height: '100%', width: '100%', boxSizing: 'border-box' }"
    >
      <el-button @click="goBack" type="primary">返回</el-button>
      <div class="graph-title">故障溯源编号：{{ route.params.alarmId }}</div>
      <div ref="myPage" style="height:calc(100vh); position: relative;">
        <RelationGraph
          ref="graphRef"
          :options="graphOptions"
          @node-click="onNodeClick"
          @line-click="onLineClick"
        >
          <template #node="{ node }">
            <div @mouseover="showNodeTips(node as RGNode, $event)" @mouseout="hideNodeTips(node as RGNode, $event)" v-if="(node as RGNode).type  === 'my-root-node'" class="my-rg-node my-root-node">
              {{ (node as RGNode).text }}
            </div>
            <div @mouseover="showNodeTips(node as RGNode, $event)" @mouseout="hideNodeTips(node as RGNode, $event)" v-else class="my-rg-node">{{ (node as RGNode).text }}</div>
          </template>
        </RelationGraph>
        <div class="node-tips" v-if="isShowNodeTipsPanel">
          <div class="node-tips-title">节点编号: {{ currentNode.text || '' }}</div>
          <div class="c-node-menu-item">物理意义： {{ currentNode.data?.detail || '' }}</div>
        </div>
      </div>
    </el-card>
    
    <!-- 右侧面板 -->
    <div class="right-panel">
      <el-card class="advice-card" shadow="hover">
        <div style="display: flex; justify-content: space-between; align-items: center">
          <span style="font-weight: bold">故障指导意见</span>
          <el-button size="small" type="success" @click="generateAdvice" :disabled="isTyping"
            >生成指导意见</el-button
          >
        </div>
        <div class="advice-content">{{ adviceContent }}</div>
      </el-card>
      <el-card class="trend-card" shadow="hover">
        <template #header>
          <span>传感器趋势分析</span>
        </template>
        <SensorDetailChart
          v-if="selectedSensorId"
          :sensorId="selectedSensorId"
          :deviceName="selectedDeviceName"
          style="height: 100%;"
        />
      </el-card>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import RelationGraph from 'relation-graph-vue3'
import type {
  RGOptions,
  RGJsonData,
  RGNode,
  RGLine,
  RGLink,
  RGUserEvent,
  RelationGraphComponent,
} from 'relation-graph-vue3'
import { useRouter, useRoute } from 'vue-router'
import SensorDetailChart from '../components/AnomalyDetection/SensorDetailChart.vue'

// 定义节点接口
interface NodeData {
  text?: string;
  data?: { detail?: string };
}

const route = useRoute()
const router = useRouter()

const goBack = () => {
  router.go(-1) // 返回上一个页面
}

//关系图部分
const myPage = ref()
const graphRef = ref<RelationGraphComponent | null>(null)
const graphOptions: RGOptions = {
  debug: false,
  defaultJunctionPoint: 'border',
  defaultFocusRootNode: false,
  defaultLineTextOffset_y: -3,
  layout: {
    layoutName: 'center',
  },
}
const isShowNodeTipsPanel = ref(false)
const currentNode = ref<NodeData>({})



// 请求后端接口
// const showGraph = async() =>{
//   const alarmId = route.params.alarmId
//   const data = await getFaultTracingGraph(alarmId).data
//   const __graph_json_data: RGJsonData = {
//     rootId: data.rootId,
//     nodes: data.nodes,
//     lines: data.lines.map(line => {
//     const value = parseFloat(line.text)
//     const g = Math.round(255 - value * 135)
//     const lineWidth = Math.max(1.5, 3 * value)
//     return {
//       ...line,
//       color: `rgb(81,${Math.max(g, 120)},51)`,
//       lineWidth,
//     }
//   }),
//   }
//   const graphInstance = graphRef.value!.getInstance()
//   graphInstance.setJsonData(__graph_json_data).then(() => {
//     graphInstance.moveToCenter()
//     graphInstance.zoomToFit()
//   })
// }

const showGraph = async () => {
  // 这里用 alarmId 或 sensorId 作为 eventId 参数
  const sensorId = Array.isArray(route.params.sensorId)
    ? route.params.sensorId[0]
    : route.params.sensorId

  try {
    const res = await fetch(`/graph/graphDataByEventId?eventId=${sensorId}`)
    var data = await res.json()
    data = data.data
    console.log(data)
    // 处理线条颜色和宽度
    const lines = data.lines.map((line: { text: string }) => {
      const value = parseFloat(line.text)
      const g = Math.round(255 - value * 135)
      const lineWidth = Math.max(1.5, 3 * value)
      return {
        ...line,
        color: `rgb(81,${Math.max(g, 120)},51)`,
        lineWidth,
      }
    })

    // 处理节点样式（如有需要）
    const nodes = data.nodes.map((node: { id: any; label?:string }) => {
      const text = node.label
      if (node.id === data.rootId) {
        return {
          ...node,
          text,
          type: 'my-root-node',
          nodeShape: 0,
          width: 100,
          height: 100,
        }
      }
      return {
        ...node,
        text,
        nodeShape: 1,
        width: 100,
        height: 40,
      }
    })

    const __graph_json_data: RGJsonData = {
      rootId: data.rootId,
      nodes,
      lines,
    }

    const graphInstance = graphRef.value!.getInstance()
    graphInstance.setJsonData(__graph_json_data).then(() => {
      graphInstance.moveToCenter()
      graphInstance.zoomToFit()
    })
  } catch (e) {
    console.error('获取关系图数据失败', e)
  }
}

// 创建线条对象的辅助函数
const createLine = (config: {
  from: string;
  to: string;
  text: string;
  lineShape?: number;
  fromJunctionPoint?: string;
  toJunctionPoint?: string;
}) => {
  const baseConfig: any = {
    from: config.from,
    to: config.to,
    text: config.text,
  }
  
  if (config.lineShape !== undefined) {
    baseConfig.lineShape = config.lineShape
  }
  if (config.fromJunctionPoint) {
    baseConfig.fromJunctionPoint = config.fromJunctionPoint
  }
  if (config.toJunctionPoint) {
    baseConfig.toJunctionPoint = config.toJunctionPoint
  }
  
  return baseConfig
}

// const showGraph = () => {
//   console.log(route.params.sensorId)
  
//   // 创建线条配置
//   const lineConfigs = [
//     createLine({ from: 'a', to: 'b', text: '0.70' }),
//     createLine({ from: 'a', to: 'c', text: '0.12', lineShape: 6 }),
//     createLine({
//       from: 'a',
//       to: 'e',
//       text: '0.05',
//       lineShape: 6,
//       fromJunctionPoint: 'border',
//       toJunctionPoint: 'left',
//     }),
//     createLine({
//       from: 'a',
//       to: 'f',
//       text: '0.10',
//       lineShape: 6,
//       fromJunctionPoint: 'border',
//       toJunctionPoint: 'bottom',
//     }),
//     createLine({ from: 'a', to: 'g', text: '0.43', lineShape: 1 }),
//     createLine({
//       from: 'f',
//       to: 'g',
//       text: '0.2',
//       lineShape: 6,
//       fromJunctionPoint: 'left',
//       toJunctionPoint: 'left',
//     }),
//   ].map((line) => {
//     const value = parseFloat(line.text)
//     // g通道范围限制在120~255，值越大g越小
//     const g = Math.round(255 - value * 135)
//     // 线宽最小1.5，最大3
//     const lineWidth = Math.max(1.5, 3 * value)
//     return {
//       ...line,
//       color: `rgb(30,${Math.max(g, 120)},255)`,
//       lineWidth,
//     }
//   })

//   const __graph_json_data = {
//     rootId: 'a',
//     nodes: [
//       {
//         id: 'a',
//         text: Array.isArray(route.params.sensorId)
//           ? route.params.sensorId[0]
//           : route.params.sensorId,
//         data: { detail: '流量指示调节器' },
//         type: 'my-root-node',
//         nodeShape: 0,
//         width: 100,
//         height: 100,
//       },
//       { id: 'b', text: 'FIC1002', data: { detail: '流量指示调节器' }, nodeShape: 1, width: 100, height: 40 },
//       { id: 'c', text: 'LV3125', data: { detail: '液位控制阀' }, nodeShape: 1, width: 100, height: 40 },
//       { id: 'e', text: 'PIC1003', data: { detail: '用于压力测量与控制的回路中的压力控制器' }, nodeShape: 1, width: 100, height: 40 },
//       { id: 'f', text: 'FV3134', data: { detail: '流量控制阀' }, nodeShape: 1, width: 100, height: 40 },
//       { id: 'g', text: 'LV31221', data: { detail: '液位控制阀' }, nodeShape: 1, width: 100, height: 40 },
//     ],
//     lines: lineConfigs,
//   } as RGJsonData // 整体进行类型断言

//   console.log(graphRef.value)
//   const graphInstance = graphRef.value!.getInstance()
//   graphInstance.setJsonData(__graph_json_data).then(() => {
//     graphInstance.moveToCenter()
//     graphInstance.zoomToFit()
//   })
// }

const onNodeClick = (nodeObject: RGNode, $event: RGUserEvent) => {
  console.log('onNodeClick:', nodeObject)
  // 点击节点仅更新下方的传感器趋势图
  if (nodeObject.text) {
    selectedSensorId.value = nodeObject.text
  }
}

const onLineClick = (lineObject: RGLine, linkObject: RGLink, $event: RGUserEvent) => {
  console.log('onLineClick:', lineObject)
}

const showNodeTips = (nodeObject: RGNode, $event: any) => {
  currentNode.value = nodeObject
  isShowNodeTipsPanel.value = true
}

const hideNodeTips = (nodeObject: RGNode, $event: any) => {
  isShowNodeTipsPanel.value = false
}

//指导意见部分
const adviceContent = ref('') // 初始为空，等待按钮点击
const isTyping = ref(false)

// 根节点ID，用于生成唯一的指导意见，此值在页面加载后不应改变
const rootSensorId =
  (Array.isArray(route.params.sensorId) ? route.params.sensorId[0] : route.params.sensorId) ||
  'FIC1001'

// 当前选中的传感器ID，仅用于更新下方的趋势图
const selectedSensorId = ref(rootSensorId)
const selectedDeviceName = ref('装置A') // 如有更准确的装置名可动态赋值

// 为不同传感器预设的指导意见
const presetAdvices: { [key: string]: string } = {
  FIC1001: `当前故障根节点为 FIC1001。\n1. 检测到 FIC1001 与 FIC1002 强相关(0.70)，优先检查 FIC1002 阀门状态。\n2. FIC1001 与 LV31221 存在中等相关性(0.43)，检查液位计 LV31221 读数是否异常。\n3. 综合分析，建议首先排查下游 FIC1002 的物理状态。`,
  FIC1002: `FIC1002 流量计异常。\n1. 该传感器是 FIC1001 的强相关下游，请检查其与 FIC1001 的物理连接和信号传输。\n2. 检查该流量计自身是否存在堵塞或损坏。\n3. 建议与 FIC1001 数据进行比对分析。`,
  LV3125: `LV3125 液位计数据显示异常。\n1. 与主故障点 FIC1001 关联较弱(0.12)，可能为独立故障或传感器漂移。\n2. 检查该液位计的电源和信号线路。\n3. 建议进行单点校准。`,
  PIC1003: `PIC1003 压力传感器异常。\n1. 与主故障点 FIC1001 关联最弱(0.05)，大概率为独立故障事件。\n2. 请检查压力传感器是否损坏或需要校准。\n3. 检查其所在管线的物理状态，排除堵塞可能。`,
  FV3134: `FV3134 阀门开度异常。\n1. 与主故障点 FIC1001 存在弱关联(0.10)，可能是故障向该阀门传播的表征。\n2. 同时与 LV31221 (0.2) 相关，检查该阀门是否受错误液位信号影响。\n3. 建议检查阀门执行器和控制器。`,
  LV31221: `LV31221 液位计异常。\n1. 与主故障点 FIC1001 中度相关(0.43)，是排查的关键路径之一。\n2. 同时受 FV3134 阀门影响，需综合判断是阀门问题导致液位异常，还是液位异常导致阀门动作。\n3. 建议检查液位计的探头和线路。`,
}

const typeAdvice = async (text: string, speed = 30) => {
  adviceContent.value = ''
  isTyping.value = true
  for (let i = 0; i < text.length; i++) {
    adviceContent.value += text[i]
    await new Promise((resolve) => setTimeout(resolve, speed))
  }
  isTyping.value = false
}

const generateAdvice = async () => {
  // TODO: 这里预留后端接口调用位置，替换为实际接口请求
  // const res = await fetch(`/api/advice/${rootSensorId}`) // 使用根节点ID
  // const data = await res.json()
  // await typeAdvice(data.advice)

  // --- 使用预设的指导意见 ---
  // 指导意见始终基于页面加载时的根节点ID
  const currentAdvice =
    presetAdvices[rootSensorId] ||
    `暂无针对 ${rootSensorId} 的详细指导意见。请检查设备常规状态。`
  await typeAdvice(currentAdvice)
}

onMounted(async () => {
  showGraph()
  // 页面加载时不自动生成指导意见
})
</script>

<style lang="scss" scoped>
.p2 {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  height: 100vh; /* 占满整个视口高度 */
  margin: 0;
  padding: 0;
  background: #f5f6fa;
}

.graph-card {
  width: 55vw;           /* 左侧占60%视口宽度 */
  min-width: 700px;
  max-width: 1000px;
  height: 92vh;          /* 上下留点边距 */
  margin: 4vh 1vw 4vh 1vw;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

.my-rg-node {
  display: flex;
  place-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  box-sizing: border-box;
}

.my-root-node {
  border: #519633 solid 2px;
  border-radius: 50%;
}

.graph-title {
  font-size: 20px;
  font-weight: bold;
  color: #4752b7;
  margin: 20px 0 10px 0;
  text-align: center;
}

.right-panel {
  display: flex;
  flex-direction: column;
  width: 28vw;           /* 右侧占32%视口宽度 */
  min-width: 350px;
  max-width: 500px;
  height: 92vh;
  margin: 4vh 2vw 4vh 0vw; /* 右边距缩小，靠近右边界 */
  box-sizing: border-box;
}

.advice-card, .trend-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin-bottom: 20px;
}

.advice-card {
  min-height: 220px;
}

.advice-content {
  flex: 1;
  margin-top: 10px;
  white-space: pre-line;
  overflow-y: auto;
  min-height: 60px;
}

.trend-card {
  min-height: 300px;
  margin-bottom: 0;
}
.trend-card :deep(.el-card__body) {
  flex: 1;
  padding: 0;
}

.node-tips{
  position: absolute;
  left: 0;
  top: 0;
  z-index: 999;
  padding: 10px;
  background-color: #ffffff;
  border: #eeeeee solid 1px;
  box-shadow: 0px 0px 8px #cccccc;
}
.node-tips-title {
  line-height: 25px;
  padding-left: 10px;
  color: #888888;
  font-size: 12px;
}

.c-node-menu-item{
  line-height: 30px;padding-left: 10px;cursor: pointer;color: #444444;font-size: 14px;border-top:#efefef solid 1px;
}
.c-node-menu-item:hover{
  background-color: rgba(66,187,66,0.2);
}
</style>